package com.zhima.sdk.utils;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;
import android.webkit.WebSettings;

import com.zhima.sdk.model.DeviceInfo;

import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by Bin on 2018/2/1.
 */

public class ZMDeviceUtil {


    public static DeviceInfo getDeviceInfo(Context context) {
        DeviceInfo magicInfo = new DeviceInfo();


        try {
            String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            magicInfo.setAndroidId(checkEmpty(androidId));
        } catch (Exception e) {
        }


        // phone
        try {
            TelephonyManager tm =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

            magicInfo.setImei(checkEmpty(tm.getDeviceId()));
            magicInfo.setImsi(checkEmpty(tm.getSubscriberId()));
            magicInfo.setDeviceSoftwareVersion(checkEmpty(tm.getDeviceSoftwareVersion()));
            magicInfo.setVoiceMailNum(checkEmpty(tm.getVoiceMailNumber()));
            magicInfo.setLine1Num(checkEmpty(tm.getLine1Number()));
            magicInfo.setSimSerialNum(checkEmpty(tm.getSimSerialNumber()));
            magicInfo.setSimOperator(checkEmpty(tm.getSimOperator()));
            magicInfo.setSimOperatorName(checkEmpty(tm.getSimOperatorName()));
            magicInfo.setSimState(checkEmpty(tm.getSimState() + ""));
            magicInfo.setPhoneType(checkEmpty(tm.getPhoneType() + ""));
            magicInfo.setPhoneNetworkType(checkEmpty(tm.getNetworkType() + ""));
            magicInfo.setPhoneNetworkOperator(checkEmpty(tm.getNetworkOperator()));
            magicInfo.setPhoneNetworkOperatorName(checkEmpty(tm.getNetworkOperatorName()));
            magicInfo.setPhoneNetworkCountryIso(checkEmpty(tm.getNetworkCountryIso()));

        } catch (Exception e) {
        }

        // Build
        try {
            magicInfo.setBuildBrand(checkEmpty(Build.BRAND));
            magicInfo.setBuildModel(checkEmpty(Build.MODEL));
            magicInfo.setBuildProduct(checkEmpty(Build.PRODUCT));
            magicInfo.setBuildManufacturer(checkEmpty(Build.MANUFACTURER));
            magicInfo.setBuildRelease(checkEmpty(Build.VERSION.RELEASE));
            magicInfo.setBuildSdk(checkEmpty(Build.VERSION.SDK));
            magicInfo.setBuildSdkInt(checkEmpty(Build.VERSION.SDK_INT + ""));
            magicInfo.setBuildSerial(checkEmpty(Build.SERIAL));
            magicInfo.setBuildHardware(checkEmpty(Build.HARDWARE));
            magicInfo.setBuildDevice(checkEmpty(Build.DEVICE));
            magicInfo.setBuildCpuAbi(checkEmpty(Build.CPU_ABI));
            magicInfo.setBuildCpuAbi2(checkEmpty(Build.CPU_ABI2));
            magicInfo.setBuildBoard(checkEmpty(Build.BOARD));
            magicInfo.setBuildDisplay(checkEmpty(Build.DISPLAY));
            magicInfo.setBuildBootloader(checkEmpty(Build.BOOTLOADER));
            magicInfo.setBuildTags(checkEmpty(Build.TAGS));
            magicInfo.setBuildType(checkEmpty(Build.TYPE));
            magicInfo.setBuildId(checkEmpty(Build.ID));
            magicInfo.setBuildIncremental(checkEmpty(Build.VERSION.INCREMENTAL));
            magicInfo.setBuildCodename(checkEmpty(Build.VERSION.CODENAME));
            magicInfo.setBuildFingerprint(checkEmpty(Build.FINGERPRINT));
            magicInfo.setBuildTime(checkEmpty(Build.TIME + ""));
            magicInfo.setBuildUser(checkEmpty(Build.USER));
            magicInfo.setBuildHost(checkEmpty(Build.HOST));

        } catch (Exception e) {
        }

        // wifi
        try {
            WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInfo = wifi.getConnectionInfo();

            magicInfo.setWifiMac(checkEmpty(getMacAddress(context)));
            magicInfo.setWifiSSID(checkEmpty(wifiInfo.getSSID()));
            magicInfo.setWifiBSSID(checkEmpty(wifiInfo.getBSSID()));

        } catch (Exception e) {
        }

        // bluetooth

        try {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
                magicInfo.setBluetoothAddress(getBluetoothAddress(context));
                magicInfo.setBluetoothName(getBluetoothName(context));
            } else  {
                magicInfo.setBluetoothAddress("");
                magicInfo.setBluetoothName("");
            }
        } catch (Exception e) {
            magicInfo.setBluetoothAddress("");
            magicInfo.setBluetoothName("");
        }


        // System
        try {
            magicInfo.setOsName(checkEmpty(System.getProperty("os.name")));
            magicInfo.setOsArch(checkEmpty(System.getProperty("os.arch")));
            magicInfo.setOsVersion(checkEmpty(System.getProperty("os.version")));
        } catch (Exception e) {
        }


        // web
        try {
            magicInfo.setUserAgent(getUserAgent(context.getApplicationContext()));
        } catch (Exception e) {
        }


        try {
            NetworkInfo networkInfo = ((ConnectivityManager) context.getSystemService(
                    Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isAvailable()) {
                magicInfo.setNetworkType(checkEmpty(networkInfo.getType() + ""));
                magicInfo.setNetworkTypeName(checkEmpty(networkInfo.getTypeName()));
                magicInfo.setNetworkSubtype(checkEmpty(networkInfo.getSubtype() + ""));
                magicInfo.setNetworkSubtypeName(checkEmpty(networkInfo.getSubtypeName()));
            } else {
                magicInfo.setNetworkType("");
                magicInfo.setNetworkTypeName("");
                magicInfo.setNetworkSubtype("");
                magicInfo.setNetworkSubtypeName("");
            }


        } catch (Exception e) {
        }

        // screen
        try {
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            String screenWidth = "";
            String screenHeight = "";
            if (wm == null) {
                screenWidth = context.getResources().getDisplayMetrics().widthPixels + "";
                screenHeight = context.getResources().getDisplayMetrics().heightPixels + "";
            } else {
                Point point = new Point();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    wm.getDefaultDisplay().getRealSize(point);
                } else {
                    wm.getDefaultDisplay().getSize(point);
                }
                screenWidth = point.x + "";
                screenHeight = point.y + "";
            }
            magicInfo.setScreenWidth(checkEmpty(screenWidth));
            magicInfo.setScreenHeight(checkEmpty(screenHeight));
            String density = context.getResources().getDisplayMetrics().density + "";
            String densityDpi = context.getResources().getDisplayMetrics().densityDpi + "";
            magicInfo.setScreenDensity(checkEmpty(density));
            magicInfo.setScreenDensityDpi(checkEmpty(densityDpi));

        } catch (Exception e) {
        }


        return magicInfo;
    }


    public static String getUserAgent(Context context) {
        String userAgent = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            try {
                userAgent = WebSettings.getDefaultUserAgent(context);
            } catch (Exception e) {
                userAgent = System.getProperty("http.agent");
            }
        } else {
            userAgent = System.getProperty("http.agent");
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0, length = userAgent.length(); i < length; i++) {
            char c = userAgent.charAt(i);
            if (c <= '\u001f' || c >= '\u007f') {
                sb.append(String.format("\\u%04x", (int) c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }


    private static String checkEmpty(String str) {
        if (TextUtils.isEmpty(str)) {
            return "";
        } else {
            return str;
        }
    }


    @TargetApi(18)
    private static String getBluetoothAddress(Context context) {
        BluetoothManager btManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter btAdapter = btManager.getAdapter();

        String btMac;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            btMac = android.provider.Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
        } else {
            btMac = btAdapter.getAddress();
        }

        return checkEmpty(btMac);

    }

    @TargetApi(18)
    private static String getBluetoothName(Context context) {
        BluetoothManager btManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter btAdapter = btManager.getAdapter();

        return checkEmpty(btAdapter.getName());

    }


    private static String getBluetoothAddressV2(BluetoothAdapter btAdapter) {
        if (Build.VERSION.SDK_INT < 23) {
            return btAdapter.getAddress();
        } else {
            return getBluetoothAddressSdk23(btAdapter);
        }
    }


    @TargetApi(23)
    static String getBluetoothAddressSdk23(BluetoothAdapter adapter) {
        if (adapter == null) return null;

        Class<? extends BluetoothAdapter> btAdapterClass = adapter.getClass();
        try {
            Class<?> btClass = Class.forName("android.bluetooth.IBluetooth");
            Field bluetooth = btAdapterClass.getDeclaredField("mService");
            bluetooth.setAccessible(true);
            Method btAddress = btClass.getMethod("getAddress");
            btAddress.setAccessible(true);
            return (String) btAddress.invoke(bluetooth.get(adapter));
        } catch (Exception e) {
            return adapter.getAddress();
        }
    }


    private static NetworkInfo getActiveNetworkInfo(Context context) {
        ConnectivityManager manager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (manager == null) return null;
        return manager.getActiveNetworkInfo();
    }


    public static boolean isConnected(Context context) {
        NetworkInfo info = getActiveNetworkInfo(context);
        return info != null && info.isConnected();
    }




    public static String getDeviceId(Context context) {
        try {
            final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            if (!"9774d56d682e549c".equals(androidId)) {
                return androidId;
            } else {
                return "";
            }
        } catch (Exception e) {
            return "";
        }

    }


//    public static String getMacAddress(Context context) {
//        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//            return getMacAddressFromWifiInfo(context);
//        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
//
//        }
//
//    }

    private static String getMacAddressFromWifiInfo(Context context) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String macAddress = wifiInfo.getMacAddress();
        return macAddress;

    }


    /**
     * 获取mac地址
     *
     * @param context
     * @return
     */
    public static String getMacAddress(Context context) {

        //如果是6.0以下，直接通过wifimanager获取
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            String macAddress0 = getMacAddress0(context);
            if (!TextUtils.isEmpty(macAddress0)) {
                return macAddress0;
            }
        }

        String str = "";
        String macSerial = "";
        try {
            Process pp = Runtime.getRuntime().exec(
                    "cat /sys/class/net/wlan0/address");
            InputStreamReader ir = new InputStreamReader(pp.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);

            for (; null != str; ) {
                str = input.readLine();
                if (str != null) {
                    macSerial = str.trim();// 去空格
                    break;
                }
            }
        } catch (Exception ex) {
        }
        if (macSerial == null || "".equals(macSerial)) {
            try {
                return loadFileAsString("/sys/class/net/eth0/address")
                        .toUpperCase().substring(0, 17);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return macSerial;
    }


    private static String getMacAddress0(Context context) {
        if (isAccessWifiStateAuthorized(context)) {
            WifiManager wifiMgr = (WifiManager) context
                    .getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInfo = null;
            try {
                wifiInfo = wifiMgr.getConnectionInfo();
                return wifiInfo.getMacAddress();
            } catch (Exception e) {
                Log.e("----->" + "NetInfoManager", "getMacAddress0:" + e.toString());
            }

        }
        return "";

    }

    /**
     * Check whether accessing wifi state is permitted
     *
     * @param context
     * @return
     */
    private static boolean isAccessWifiStateAuthorized(Context context) {
        if (PackageManager.PERMISSION_GRANTED == context
                .checkCallingOrSelfPermission("android.permission.ACCESS_WIFI_STATE")) {
            Log.e("----->" + "NetInfoManager", "isAccessWifiStateAuthorized:" + "access wifi state is enabled");
            return true;
        } else
            return false;
    }


    private static String loadFileAsString(String fileName) throws Exception {
        FileReader reader = new FileReader(fileName);
        String text = loadReaderAsString(reader);
        reader.close();
        return text;
    }

    private static String loadReaderAsString(Reader reader) throws Exception {
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[4096];
        int readLength = reader.read(buffer);
        while (readLength >= 0) {
            builder.append(buffer, 0, readLength);
            readLength = reader.read(buffer);
        }
        return builder.toString();
    }




}
